package castledefense.sound;

import java.util.ArrayList;

import castledefense.data.Resources;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;

public final class SoundHandler {
	private static boolean mute = false;
	private static boolean disabled = false;
	private static float volume = 1f;

	static final private String filePath = Resources.filesPath;

	private static ArrayList<DelayedSfx> delayedList = new ArrayList<DelayedSfx>(
			4);
	private static ArrayList<Sfx> sfxList;

	private static Sfx fire;
	private static Sfx water;
	private static Sfx lightning;
	private static Sfx building;
	private static Sfx blessedWind;
	private static Sfx pyromancer;
	private static Sfx quake;
	private static Sfx flood;
	private static Sfx missile;
	private static Sfx click;

	public static void init() {
		sfxList = new ArrayList<Sfx>(32);
		fire = addSfx("fire", 150, 0.03f);
		water = addSfx("water", 150, 0.075f);
		lightning = addSfx("lightning", 250, 0.1f);
		building = addSfx("building", 600, 0.05f);
		blessedWind = addSfx("blessedwind", 100, 1f);
		pyromancer = addSfx("pyromancer", 100, 1f);
		quake = addSfx("quakeplaceholder", 100, 1f);
		flood = addSfx("flood", 100, 1f);
		missile = addSfx("missile", 200, 0.01f);
		click = addSfx("click", 100, 0.5f);
	}

	public static void dispose() {
		lightning.sound.dispose();
		pyromancer.sound.dispose();
		flood.sound.dispose();
		blessedWind.sound.dispose();
		quake.sound.dispose();
		click.sound.dispose();
		missile.sound.dispose();
		building.sound.dispose();
		water.sound.dispose();
		fire.sound.dispose();
	}

	public static final void update(int delta) {

		final int size = sfxList.size();
		for (int i = 0; i < size; i++) {
			sfxList.get(i).cooldown -= delta;
		}

		int size2 = delayedList.size();
		for (int i = 0; i < size2; i++) {
			if (delayedList.get(i).update(delta)) {
				delayedList.remove(i);
				size2--;
			}
		}
	}

	public static final boolean isMute() {
		return mute;
	}

	public static final void setMute(boolean newValue) {
		if (!disabled) {
			mute = newValue;
			if (newValue) {
				final int size = sfxList.size();
				for (int i = 0; i < size; i++) {
					sfxList.get(i).sound.stop();

				}
			}

		}
	}

	public static final float getVolume() {
		return volume;
	}

	public static final void setVolume(float newVolume) {
		volume = newVolume;
		if (volume > 1f)
			volume = 1f;
		if (volume < 0f)
			volume = 0f;
	}

	public final static void fireSound() {
		if (!mute) {
			fire.play();
		}
	}

	public final static void waterSound() {
		if (!mute) {
			water.play();
		}
	}

	public final static void buildingSound() {
		if (!mute) {
			building.play();
		}
	}

	public final static void lightningSound() {
		if (!mute) {
			lightning.play();
		}
	}

	public final static void pyromancerSound() {
		if (!mute) {
			pyromancer.play();
		}
	}

	public final static void floodSound() {
		if (!mute) {
			flood.play();
		}
	}

	public final static void blessedWindSound() {
		if (!mute) {
			blessedWind.play();
			addDelayedSfx(blessedWind, 400, 0.8f);
		}
	}

	public final static void quakeSound() {
		if (!mute) {
			quake.play();
			addDelayedSfx(quake, 200, 0.5f);
			addDelayedSfx(quake, 300, 0.25f);
		}
	}

	public final static void clickSound() {
		if (!mute) {
			click.play();
		}
	}

	public final static void missileSound() {
		if (!mute) {
			missile.play();

		}
	}

	private static Sfx addSfx(String name, int timeBeetweenSounds, float vol) {
		Sfx tmp = new Sfx(Gdx.audio.newSound(Gdx.files.internal(filePath
				+ name+".ogg")), timeBeetweenSounds, vol);
		sfxList.add(tmp);
		return tmp;
	}

	private static void addDelayedSfx(Sfx sfx, int timer, float vol) {
		delayedList.add(new DelayedSfx(sfx, timer, vol));
	}

	private static class DelayedSfx {
		private Sfx sfx;
		private int timer;
		private float vol;

		private DelayedSfx(Sfx eff, int timer, float vol) {
			sfx = eff;
			this.timer = timer;
			this.vol = vol;
		}

		boolean update(int delta) {
			if (timer > 0) {
				timer -= delta;
			} else {
				sfx.play(volume * sfx.vol * vol);
				return true;
			}
			return false;
		}

	}

	private static class Sfx {
		private final Sound sound;
		private int cooldown = 0;
		private int timeBeetweenSounds;
		private float vol;

		protected Sfx(Sound sound, int timeBeetweenSounds, float vol) {
			this.sound = sound;
			this.timeBeetweenSounds = timeBeetweenSounds;
			this.vol = vol;
		}

		private void play(float f) {
			if (cooldown <= 0) {
				sound.play(f * vol * volume);
				cooldown = timeBeetweenSounds;
			}
		}

		private void play() {
			if (cooldown <= 0) {
				sound.play(vol * volume);
				cooldown = timeBeetweenSounds;
			}
		}
	}

}
